package cn.donzell.app.view;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import cn.donzell.app.limit.NumberTextField;
import cn.donzell.app.model.Address;
import cn.donzell.app.model.Identity;
import cn.donzell.app.utils.ConstAreaUtil;
import cn.donzell.app.utils.ExcelUtils;
import cn.donzell.app.utils.IdCardGenerator;
import cn.donzell.app.utils.NameGenerator;
import javafx.scene.control.ComboBox;

public class MainForm extends JFrame {
	private static final long serialVersionUID = 1L;



	private JComboBox<String> provinceComboBox = null;
	private JComboBox<String> cityComboBox = null;
	private JComboBox<String> areaComboBox = null;
	private JComboBox<String> yearBeginComboBox = null;
	private JComboBox<String> yearEndComboBox = null;
	private JComboBox<String> sexComboBox = null;
	private JTextField genNumText = null;

	// 存放区域id的集合
	private static Map<String, Address> citymap = new HashMap<String, Address>();
	// 存放区域id的集合
	private static Map<String, Integer> areamap = new HashMap<String, Integer>();

	public MainForm() throws IOException {
		JFrame frame = new JFrame("身份证批量生成工具");
		JPanel panel = new JPanel();
		frame.add(panel);

		/*
		 * 调用用户定义的方法并添加组件到面板
		 */
		placeComponents(panel);
		frame.setSize(600, 250);
		frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
		frame.setResizable(false); // 设置JFrame是否可以改变大小
		frame.setLocationRelativeTo(getOwner());// 打开后居中
		frame.setVisible(true);
		frame.setIconImage(ImageIO.read(new File("img/icon.jpg")));
		frame.setDefaultCloseOperation(EXIT_ON_CLOSE); // 关闭后程序释放内存
	}

	public static void main(String args[]) throws IOException {
		new MainForm();
	}

	private void placeComponents(JPanel panel) {
		panel.setLayout(null);
		// 地区
		JLabel userLabel = new JLabel("出生地区:");
		userLabel.setBounds(10, 10, 80, 25);
		panel.add(userLabel);

		provinceComboBox = new JComboBox<String>();
		provinceComboBox.setBounds(100, 10, 120, 25);
		addProvinceItem(provinceComboBox);
		// 省的监听事件
		provinceComboBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				String province = (String) provinceComboBox.getSelectedItem();// 获得省市份框对象
				addCityItem(cityComboBox, province);
			}
		});
		panel.add(provinceComboBox);

		cityComboBox = new JComboBox<String>();
		cityComboBox.setBounds(240, 10, 110, 25);
		// 市的监听事件
		cityComboBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				String city = (String) cityComboBox.getSelectedItem();// 获得市县框对象
				addAreaItem(areaComboBox, city);
			}
		});
		panel.add(cityComboBox);


		areaComboBox = new JComboBox<String>();
		areaComboBox.setBounds(360, 10, 110, 25);
		String area = (String) cityComboBox.getSelectedItem();// 获得区框对象
		panel.add(areaComboBox);


		// 年龄段
		JLabel yearLabel = new JLabel("出生年份:");
		yearLabel.setBounds(10, 50, 80, 25);
		panel.add(yearLabel);

		yearBeginComboBox = new JComboBox<String>();
		yearBeginComboBox.setBounds(100, 50, 80, 25);
		addYearItem(yearBeginComboBox);
		panel.add(yearBeginComboBox);

		JLabel yearSplitLabel = new JLabel("至");
		yearSplitLabel.setBounds(200, 50, 50, 25);
		panel.add(yearSplitLabel);

		yearEndComboBox = new JComboBox<String>();
		yearEndComboBox.setBounds(230, 50, 80, 25);
		addYearItem(yearEndComboBox);
		panel.add(yearEndComboBox);
		// 性别
		JLabel sexLabel = new JLabel("性        别:");
		sexLabel.setBounds(10, 90, 80, 25);
		panel.add(sexLabel);

		sexComboBox = new JComboBox<String>();
		sexComboBox.setBounds(100, 90, 80, 25);
		sexComboBox.addItem("随机");
		sexComboBox.addItem("男");
		sexComboBox.addItem("女");
		panel.add(sexComboBox);
		// 生成个数
		JLabel genNumLabel = new JLabel("生成个数:");
		genNumLabel.setBounds(10, 130, 80, 25);
		panel.add(genNumLabel);

		genNumText = new JTextField();
		genNumText.setBounds(100, 130, 80, 25);
		genNumText.setDocument(new NumberTextField(7));
		panel.add(genNumText);

		JButton genBtn = new JButton("批量生成");
		genBtn.setBounds(150, 170, 100, 25);
		genBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				genExcel();
			}
		});
		panel.add(genBtn);
	}

	private void genExcel() {
		if (!doValidate()) {
			return;
		}
		String province = (String) provinceComboBox.getSelectedItem();
		String city = (String) cityComboBox.getSelectedItem();
		String area = (String) areaComboBox.getSelectedItem();// 获得区域框对象
		String yearBegin = (String) yearBeginComboBox.getSelectedItem();
		String yearEnd = (String) yearEndComboBox.getSelectedItem();
		String sex = (String) sexComboBox.getSelectedItem();
		String genNum = (String) genNumText.getText();

		SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd_HHmmss");
		String fileName = dateformat.format(new Date()) + ".xlsx";
		JFileChooser chooser = new JFileChooser();
		chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		if (JFileChooser.APPROVE_OPTION == chooser.showSaveDialog(this)) {
			String saveFilePath = chooser.getSelectedFile().getPath();
			saveFilePath = saveFilePath + File.separator + fileName;// 写入文件
			int size = Integer.valueOf(genNum) > 1000000 ? 1000000 : Integer.valueOf(genNum);
			new ArrayList<Identity>();
			Integer areaCode = areamap.get(area);
			List<Identity> identities = new ArrayList<Identity>();
			for (int i = 0; i < size; i++) {
				String name = NameGenerator.generate();
				Identity identity = IdCardGenerator.generate(areaCode, yearBegin, yearEnd, sex);
				identity.setName(name);
				identity.setArea(province + " "+city+" " + area);
				identities.add(identity);
			}
			ExcelUtils.createExcel(identities, saveFilePath);
			JOptionPane.showMessageDialog(new JFrame(), "操作成功!");
		}
	}

	public boolean doValidate() {
		String province = (String) provinceComboBox.getSelectedItem();// 获得省份框对象
		if (null == province) {
			JOptionPane.showMessageDialog(new JFrame(), "请选择省份!");
			return false;
		}
		String city = (String) cityComboBox.getSelectedItem();// 获得区域框对象
		if (null == city) {
			JOptionPane.showMessageDialog(new JFrame(), "请选择城市!");
			return false;
		}
		String area = (String) areaComboBox.getSelectedItem();// 获得区域框对象
		if (null == area) {
			JOptionPane.showMessageDialog(new JFrame(), "请选择区县!");
			return false;
		}
		String yearBegin = (String) yearBeginComboBox.getSelectedItem();
		String yearEnd = (String) yearEndComboBox.getSelectedItem();
		if (Integer.valueOf(yearBegin) > Integer.valueOf(yearEnd)) {
			JOptionPane.showMessageDialog(new JFrame(), "开始年份不能大于结束年份!");
			return false;
		}
		String genNum = (String) genNumText.getText();
		if ("".equals(genNum)) {
			JOptionPane.showMessageDialog(new JFrame(), "请先填写生成个数!");
			return false;
		}
		return true;
	}

	private static void addYearItem(JComboBox<String> comboBox) {
		int begin = getCurrentYear();
		for (int i = begin; i > (begin - 100); i--) {
			comboBox.addItem(String.valueOf(i));
		}
	}

	public static Integer getCurrentYear() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
		Date date = new Date();
		return Integer.valueOf(sdf.format(date));
	}

	private static void addProvinceItem(JComboBox<String> comboBox) {
		List<Address> datas = ConstAreaUtil.addressList;
		for (Address result : datas) {
			comboBox.addItem(result.getName());
		}
	}

	private static void addCityItem(JComboBox<String> comboBox, String fileName) {
		comboBox.removeAllItems();
		List<Address> addressList = ConstAreaUtil.addressList;
		List<Address> collect = addressList.stream().filter(p -> fileName.equals(p.getName())).collect(Collectors.toList());
		for (Address city : collect.get(0).getChildren()) {
			    citymap.put(city.getName(), city);
				comboBox.addItem(city.getName());
		}
	}

	private static void addAreaItem(JComboBox<String> comboBox, String fileName) {
		comboBox.removeAllItems();
		List<Address> addressList = ConstAreaUtil.addressList;
		Address address = citymap.get(fileName);
		if(address==null){
			return;
		}
		for (Address city : address.getChildren()) {
			areamap.put(city.getName(),city.getZip());
			comboBox.addItem(city.getName());
		}
	}

}
